package org.mlz.game

import com.sun.javafx.scene.traversal.Direction
import javafx.scene.input.KeyCode
import javafx.scene.input.KeyEvent
import org.itheima.kotlin.game.core.Window
import org.mlz.game.business.*
import org.mlz.game.model.*
import sun.security.krb5.internal.crypto.Des
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader
import java.util.concurrent.CopyOnWriteArrayList


/**
 *<p>
 *
 *</p>
 * CreateBy  Malingzhao
 * @date  2020/9/18
 */
class GameWindow : Window("坦克大战 - V1.0", "img/blast_11.png", Config.gameWidth, Config.gameHeight) {


    //晚点创建
    private lateinit var tank: Tank

    //管理元素的集合
//    private val views = arrayListOf<View>()
    //线程安全的集合
    private val views = CopyOnWriteArrayList<View>()

    //判断游戏是否结束
    private var gameOver: Boolean = false


    //敌方的数量
    private var enemyTotalSize: Int = 20

    //地方坦克在界面上最多显示几个
    private var enemyActivrSize: Int = 6


    //敌方的出生点
    private val enemyBornLocation = arrayListOf<Pair<Int, Int>>()


    //出生地点下标
    private var bornIndex = 0

    override fun onCreate() {

        //地图
        //通过读文件的方式创建滴入
//        val file = File(javaClass.getResource("/map/1.map").path)

        val resourceAsStream = javaClass.getResourceAsStream("/map/1.map")

        val reader = BufferedReader(InputStreamReader(resourceAsStream,"utf-8") )
        //读取文件的行
        var lines: List<String> = reader.readLines()

        var lineNum = 0
        //循环遍历
        lines.forEach {
            var columnNum = 0
            it.toCharArray().forEach { column ->

                when (column) {
                    '砖' -> views.add(Wall(columnNum * Config.block, lineNum * Config.block))
                    '铁' -> views.add(Steel(columnNum * Config.block, lineNum * Config.block))
                    '草' -> views.add(Grass(columnNum * Config.block, lineNum * Config.block))
                    '水' -> views.add(Water(columnNum * Config.block, lineNum * Config.block))
                    '敌' -> enemyBornLocation.add(Pair(columnNum * Config.block, lineNum * Config.block))
                }
                columnNum++
            }
            lineNum++
        }

        //添加我方的坦克
        tank = Tank(Config.block * 10, Config.block * 12)
        views.add(tank)

        //添加大本营
        views.add(Camp(Config.gameWidth / 2 - Config.block, Config.gameHeight - 96))
    }

    override fun onDisplay() {

        //绘制图形

        //绘制一个砖墙
//        Painter.drawImage("img/wall.gif", 100, 100)

        //绘制一个草坪
//        Painter.drawImage("img/grass.gif", 200,200)
//        wall.draw()
//        grass.draw()
        //绘制地图中的元素
        views.forEach { it.draw() }
        println("${views.size}")

    }

    override fun onKeyPressed(event: KeyEvent) {
        //用户操作的时候
        if (!gameOver) {
            when (event.code) {
                KeyCode.W -> {
                    tank.move(Direction.UP)
                }

                KeyCode.S -> {
                    tank.move(Direction.DOWN)
                }

                KeyCode.A -> {
                    tank.move(Direction.LEFT)
                }

                KeyCode.D -> {
                    tank.move(Direction.RIGHT)
                }
                KeyCode.ENTER -> {
                    //发射子弹
                    var shot = tank.shot()
                    //交给views管理
                    views.add(shot)
                }
            }
        }
    }

    override fun onRefresh() {

        //检测销毁
        views.filter { it is Destroyable }.forEach {
            //判断具备销毁能力的物体是否被销毁了

            if ((it as Destroyable).isDestroyed()) {
                views.remove(it)
                if (it is Enemy) {
                    enemyTotalSize--
                }
                val showDestroy = it.showDestroy()
                showDestroy?.let {
                    views.addAll(showDestroy)
                }
            }
        }
        //业务逻辑

        if (gameOver) return
        //判断运动的物体和阻塞物体是否发生碰撞
        //1)找到涌动的物体
        //kotlin的特性 return 的方法
        var moves = views.filter { it is Movable }.forEach { move ->
            //2)找到阻塞的物体
            var badDirection: Direction? = null
            var badBlock: Blockable? = null

            move as Movable
            views.filter { (it is Blockable) and (move != it) }.forEach blockTag@{ block ->
                //3)遍历集合,找到是否发生碰撞
                //move和block是否碰撞
                block as Blockable
                //获得碰撞的方向
                var direction: Direction? = move.willCollision(block)
                direction?.let {
                    //移动的发现碰撞 跳出当前的循环
                    badDirection = direction
                    badBlock = block
                    return@blockTag
                }
            }
            //找到和用碰撞的block,找到会碰撞的方向
            //通知可以移动的物体 会在哪个方向和物体碰撞
            move.notifyCollisionBlock(badDirection, badBlock)
        }

        //检测自动移动能力的物体 让他们自己动起来
        views.filter { it is AutoMovable }.forEach {
            (it as AutoMovable).autoMove()
        }


        //检测自动射击的能力不
        views.filter { it is AutoShot }.forEach {
            it as AutoShot

            var shot = it.autoShot()
            shot?.let {
                views.add(shot)
            }
        }

        //检测具备攻击能力和被攻击的物体之间是否产生碰撞
        //1)过滤具备攻击能力的
        views.filter { it is Attackable }.forEach { attack ->
            attack as Attackable
            //2）过滤受攻击能力的(攻击方的源不可以是发射方)
            //攻击方如果也是受攻击方, 是不可以打自己的
            views.filter { (it is Sufferable) and (attack.owner != it) and (attack != it) }
                .forEach sufferTRag@{ suffer ->
                    suffer as Sufferable
                    //3）判断是否产生碰撞
                    if (attack.isCollission(suffer)) {
                        //产生碰撞找到碰撞者
                        //通知攻击者产生碰撞了
                        attack.notifyAttack(suffer)
                        //通知被攻击者产生碰撞
                        val sufferView = suffer.notifySuffer(attack)

                        sufferView?.let {
                            //显示挨打的效果
                            views.addAll(sufferView)
                        }
                        return@sufferTRag
                    }

                }
        }

        //检测游戏结束
        if ((views.filter { it is Camp }.isEmpty()) or (enemyTotalSize <= 0)) {
            gameOver = true
        }

        //检测敌方出生
        //判断当前页面上敌方那个的数量, 小于激活数量
        if ((enemyTotalSize > 0 )and (views.filter { it is Enemy }.size < enemyActivrSize)) {
            val index = bornIndex % enemyBornLocation.size
            val pair = enemyBornLocation[index]
            views.add(Enemy(pair.first, pair.second))
            bornIndex++
        }


    }
}

